#include "mainwindow.h"
#include "ui_mainwindow.h"


#include<QPainter>
#include<QMouseEvent>
#include<math.h>
#include<QMessageBox>
#include<QTimer>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //  设置窗口大小
    setFixedSize(MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE,
                 MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE);//窗口大小=边界*2+格子个数*格子大小

    //初始化Gamemodel 游戏指针
    initialGame();

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    //绘制棋盘
    painter.setRenderHint(QPainter::Antialiasing,true);//抗锯齿？？？？

    for (int i=0;i<=BOARD_GRAD_SIZE;i++)
    {
        //从左到右，（i+1）条竖线
        painter.drawLine(MARGIN+BLOCK_SIZE*i,MARGIN,
                         MARGIN+BLOCK_SIZE*i,size().height()-MARGIN);

        //从上到下，（i+1）条横线
        painter.drawLine(MARGIN,MARGIN+BLOCK_SIZE*i,
                         size().width()-MARGIN,MARGIN+BLOCK_SIZE*i);
    }

    //绘制选中点
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    //绘制落子标记（防止鼠标出框越界）
    if(clickPosRow>0&&clickPosRow<BOARD_GRAD_SIZE&&
            clickPosCol>0&&clickPosCol<BOARD_GRAD_SIZE&&
            game->gameMapVec[clickPosRow][clickPosCol]==0)
    {
        if(game->playerflag)
            brush.setColor(Qt::black);
        else
            brush.setColor(Qt::white);
        painter.setBrush(brush);
        painter.drawRect(MARGIN+BLOCK_SIZE*clickPosCol-MARK_SIZE/2,
                         MARGIN+BLOCK_SIZE*clickPosRow-MARK_SIZE/2,
                         MARK_SIZE,MARK_SIZE);
    }


    //绘制棋子
    for (int i=0;i<BOARD_GRAD_SIZE;i++)
    {
        for (int j=0;j<BOARD_GRAD_SIZE;j++)
        {
            if(game->gameMapVec[i][j]==1)
            {
                brush.setColor(Qt::black);

                painter.setBrush(brush);
                painter.drawEllipse(MARGIN+BLOCK_SIZE*j-CHESS_R,MARGIN+BLOCK_SIZE*i-CHESS_R,CHESS_R*2,CHESS_R*2);
            }
            else if(game->gameMapVec[i][j]==-1)
            {
                brush.setColor(Qt::white);

                painter.setBrush(brush);
                painter.drawEllipse(MARGIN+BLOCK_SIZE*j-CHESS_R,MARGIN+BLOCK_SIZE*i-CHESS_R,CHESS_R*2,CHESS_R*2);


            }
        }
    }

    //判断输赢

    //位置合法且有棋子
    if(clickPosRow>0&&clickPosCol<BOARD_GRAD_SIZE&&
            clickPosCol>0&&clickPosCol<BOARD_GRAD_SIZE&&
            (game->gameMapVec[clickPosRow][clickPosCol]==1||
             game->gameMapVec[clickPosRow][clickPosCol]==-1))
    {
        if(game->IsWin(clickPosRow,clickPosCol)&&game->gamestatus==PLAYING)
        {
            //胜利
            game->gamestatus=WIN;
            //QSound::play(":sound/xin.wav");
            QString str;
            if(game->gameMapVec[clickPosRow][clickPosCol]==1)
                str="黑棋";
            else if(game->gameMapVec[clickPosRow][clickPosCol]==-1)
                str="白棋";
            QMessageBox::StandardButton btnValue=QMessageBox::information(this,"五子棋决战",str+"胜利！");

            //重置游戏状态，否则容易死循环
            if(btnValue==QMessageBox::Ok)
            {
                game->Startgame(game_type);
                game->gamestatus=PLAYING;
            }
        }
    }


}

void MainWindow::initialGame()
{
    //初始化游戏模型
    game=new Gamemodel;
    initialAIGame();
}

void MainWindow::initialAIGame()
{
    game_type=AI;
    game->gamestatus=PLAYING;

    //在数据模型中进行初始化功能
    game->Startgame(game_type);
    update();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    //通过鼠标的移动来确定落子的标记
    int x=event->x();
    int y=event->y();

    //棋盘边缘不能落子
    if(x>=MARGIN+BLOCK_SIZE/2&&
            x<size().width()-MARGIN-BLOCK_SIZE/2&&
            y>=MARGIN+BLOCK_SIZE/2&&
            y<size().height()-MARGIN-BLOCK_SIZE/2)
    {
        //获取最近的左上角的点
        //add by rock
        int col=(x-MARGIN)/BLOCK_SIZE;
        int row=(y-MARGIN)/BLOCK_SIZE;

        //距离棋盘最左上的点的距离
        int leftTopPosX=MARGIN+BLOCK_SIZE*col;
        int leftTopPosY=MARGIN+BLOCK_SIZE*row;

        //根据距离算出合适的点击位置，一共四个点，根据半径距离选最近的
        clickPosRow=-1;//初始化最终的值
        clickPosCol=-1;

        int len=0;//计算后取整

        selectPos=false;

        //确定一个误差在范围内的点，且只可能确定出一个出来
        //最左上的点
        len=sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY)*(y-leftTopPosY));
        if(len<POS_OFFSITE)
        {
            clickPosRow=row;
            clickPosCol=col;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0)
            {
                selectPos=true;
            }
        }

        //左边（0，1）的点
        len=sqrt((x-leftTopPosX-BLOCK_SIZE)*(x-leftTopPosX-BLOCK_SIZE)+(y-leftTopPosY)*(y-leftTopPosY));
        if(len<POS_OFFSITE)
        {
            clickPosRow=row;
            clickPosCol=col+1;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0)
                selectPos=true;
        }

        //坐标（1，0）的点
        len=sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY-BLOCK_SIZE)*(y-leftTopPosY-BLOCK_SIZE));
        if(len<POS_OFFSITE)
        {
            clickPosRow=row+1;
            clickPosCol=col;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0)
            {
                selectPos=true;
            }
        }

        //坐标(1,1)的点
        len=sqrt((x-leftTopPosX-BLOCK_SIZE)*(x-leftTopPosX-BLOCK_SIZE)+(y-leftTopPosY-BLOCK_SIZE)*(y-leftTopPosY-BLOCK_SIZE));
        if(len<POS_OFFSITE)
        {
            clickPosRow=row+1;
            clickPosCol=col+1;
            if(game->gameMapVec[clickPosRow][clickPosCol]==0)
            {
                selectPos=true;
            }
        }

        //存了坐标后也要重绘
        update();
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if(selectPos==false)//没选择成功
    {
        return;
    }
    else
        selectPos=false;//马上要重新落子，落子前初始化

    //由人来下棋
    chessOneByPerson();

    if(game_type==AI)
    {
        //人机模式
        //AI下棋
        QTimer::singleShot(AI_thinkingTime,this,SLOT(chessOneByAI()));
    }
}

void MainWindow::chessOneByPerson()
{
    //根据当前存储的坐标下子
    //只有点击有效，且该处没有棋子才可以落子
    if(clickPosRow!=-1&&clickPosCol!=-1&&game->gameMapVec[clickPosRow][clickPosCol]==0)
    {
        //在游戏的数据模型中落子
        game->byman(clickPosRow,clickPosCol);

        //播放落子音效，待实现

        //重绘
        update();
    }
}

void MainWindow::chessOneByAI()
{
    game->byAI(clickPosRow,clickPosCol);
    //Qsound::play(":sound/chessone.wav");
    update();
}

